package com.jswdwsx.esign.protocol

import com.jswdwsx.esign.config.EsignProperties
import com.jswdwsx.esign.service.StoredTokenService
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import java.io.IOException

/**
 * 作用1：为每个e签宝请求添加权限相关请求头
 * 作用2：当E签宝返回token认证错误时强制刷新token并重新请求
 */
class EsignTokenInterceptor(
    private val project: EsignProperties.Project,
    private val tokenService: StoredTokenService
) : Interceptor {

    private val logger = LoggerFactory.getLogger(EsignTokenInterceptor::class.java)

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {

        val request = chain.request().newBuilder()
            .addHeader("X-Tsign-Open-App-Id", project.projectId)
            .addHeader("X-Tsign-Open-Token", tokenService.token(project.projectId, project.projectSecret).token)
            .build()
        val response: Response = chain.proceed(request)

        // 判断token失效
        if (isTokenExpired(response)) {
            response.close()
            logger.info("token已失效，重新请求E签宝获取新token后重新发起请求")

            // 使用新的Token，创建新的请求
            val newRequest: Request = chain.request()
                .newBuilder()
                .addHeader("X-Tsign-Open-App-Id", project.projectId)
                .addHeader("X-Tsign-Open-Token", tokenService.tokenForceFresh(project))
                .build()

            // 重新请求
            return chain.proceed(newRequest)
        }
        return response
    }

    /**
     * 根据Response，判断Token是否失效
     *
     * @param response
     * @return
     */
    private fun isTokenExpired(response: Response): Boolean {
        return response.code == HttpStatus.UNAUTHORIZED.value()
    }
}